#ifndef APPLICATION_H
#define APPLICATION_H

#include "Common.h"

namespace GenBen {
	
// Platform-agnostic part

void criticalError(string message);

class Graphics;
class Audio;
class Input;
class Time;

class Application
{
public:
	Application(const string& title, uint width, uint height, uint scale, bool fullscreen, bool lcd);
	virtual ~Application();

	virtual void init() = 0;
	virtual void close() = 0;

	virtual void update() = 0;
	virtual void render() = 0;

	void run();

	Graphics* getGraphics();
	Audio* getAudio();
	Input* getInput();
	Time* getTime();
};

} // namespace

// Platform specific part
#ifdef GENBEN_PLATFORM_PSP
#include <pspkernel.h>

#ifdef _DEBUG
#define DEBUG_OUT(str) sceIoWrite(1, str, strlen(str)) 
#else
#define DEBUG_OUT(str)
#endif

#define IMPLEMENT_APP(App) \
PSP_MODULE_INFO("GENBENAPP", 0, 1, 0); \
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); \
PSP_HEAP_SIZE_KB(20480); \
int main(void) \
{ \
	App app; \
	app.run(); \
}
#endif

#ifdef GENBEN_PLATFORM_WIN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#ifdef _DEBUG
#define DEBUG_OUT(str) OutputDebugString(str)
#else
#define DEBUG_OUT(str)
#endif

#define IMPLEMENT_APP(App) \
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nShowCmd) \
{ \
	App app; \
	app.run(); \
}
#endif

#ifdef GENBEN_PLATFORM_LINUX

#ifdef _DEBUG
#define DEBUG_OUT(str) printf("%s", str)
#else
#define DEBUG_OUT(str)
#endif

#define IMPLEMENT_APP(App) \
int main() \
{ \
	App app; \
	app.run(); \
}
#endif

#endif
